home *** CD-ROM | disk | FTP | other *** search
- #define NOCOMM
- #include <windows.h>
- #include <dos.h>
- #include <memory.h>
- #include "getdrvx.h"
-
- #define CDS_SUBST (0x1000)
-
- #define DOS3_CDS_SIZE 81
- #define DOS4_CDS_SIZE 88
- #define CDS_PATH 0x00
- #define CDS_FLAGS 0x43
- #define CDS_DPB 0x45
-
- #define DPB_FATS 8
-
- #define MK_FP(seg,ofs) ((void far *) (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
- #define _DS GetDS()
-
- /* Documented Windows functions not declared in WINDOWS.H */
- DWORD FAR PASCAL GlobalDosAlloc(DWORD dwBytes);
- WORD FAR PASCAL GlobalDosFree(WORD wSelector);
-
- /* Undocumented Windows functions */
- VOID FAR PASCAL SetSelectorBase(WORD wSelector, DWORD dwBase);
- VOID FAR PASCAL SetSelectorLimit(WORD wSelector, DWORD dwLimit);
-
- /* Global Variables */
- WORD _wSelector; // a data selector
-
- /* Types */
- // DOS list of lists structure (for DOS 3.1 or better)
- typedef struct {
- BYTE x[22]; // (don't care)
- BYTE far* cds;
- BYTE xx[7]; // (don't care)
- BYTE lastdrive;
- // ... the rest of DOS List of Lists
- } DOSLISTS;
-
- // DPMI real-mode call structure
- typedef struct {
- DWORD edi, esi, ebp, reserved, ebx, edx, ecx, eax;
- WORD flags, es, ds, fs, gs, ip, cs, sp, ss;
- } REALMODECALL;
-
-
- int GetDosVersionMajor(void)
- {
- int dosver;
-
- _asm mov ah, 0x30;
- _asm int 0x21;
- _asm mov dosver, ax;
-
- return (BYTE)dosver;
- }
-
- unsigned GetDS(void)
- {
- _asm mov ax, ds;
- return; // return value in AX
- }
-
-
- /****************************************************************************
- BOOL DPMI_RealModeInt(int intno, REALMODECALL far* r)
-
- PURPOSE: DPMI simulate real-mode interrupt function. The
- following is an excerpt from the DPMI Specification:
-
- PARAMETERS:
- int intno real-mode interrupt to simulate
- REALMODECALL far* r
-
- RETURNS: TRUE if interrupt is successful, FALSE on error
-
- NOTES: The following is an excerpt from INTEL's DPMI specs:
-
- To Call
-
- AX = 0300h
- BL = Interrupt number
- BH = Flags
- Bit 0 = 1 resets the interrupt controller and A20
- line
- Other flags reserved and must be 0
- CX = Number of words to copy from protected mode to
- real-mode stack
- ES:(E)DI = Selector:Offset of real-mode call structure
-
- Returns
-
- If function was successful:
- Carry flag is clear.
- ES:(E)DI = Selector:Offset of modified real-mode call
- structure
-
- If function was not successful:
- Carry flag is set.
- ****************************************************************************/
- BOOL DPMI_RealModeInt(int intno, REALMODECALL far* r)
- {
- intno &= 0x00FF; // reset high byte (flags)
-
- _asm {
- push di
- mov bx, intno // flags | real-mode interrupt to call
- mov cx, 0 // don't copy anything from protected mode stack
- les di, r // es:di -> real-mode call structure
- mov ax, 0x0300 // DPMI simulate real-mode interrupt function
- int 0x31
- pop di
- jc error
- }
- return TRUE;
-
- error:
- return FALSE;
- }
-
- /****************************************************************************
- BYTE far* PMODE_ADDR(WORD wSel, BYTE far* RMODE_ADDR)
-
- PURPOSE: Get the Current Directory Structure
-
- PARAMETERS:
- WORD wSel A valid selector
- BYTE far* RMODE_ADDR A real mode address
-
- RETURNS: a protected-mode address of RMODE_ADDR
-
- NOTES: The base address of selector wSel is set to the segment of
- RMODE_ADDR.
- *****************************************************************************/
- BYTE far* PMODE_ADDR(WORD wSel, BYTE far* RMODE_ADDR)
- {
- SetSelectorBase(wSel, (DWORD) FP_SEG(RMODE_ADDR) << 4);
- return MK_FP(wSel, FP_OFF(RMODE_ADDR));
- }
-
- /****************************************************************************
- BYTE far* GetCDS(int nDrive)
-
- PURPOSE: Get the Current Directory Structure
-
- PARAMETERS: int nDrive The drive to retrieve
-
- RETURNS: a real-mode pointer to the Current Directory Structure of
- drive nDrive.
- *****************************************************************************/
- BYTE far* GetCDS(int nDrive)
- {
- DOSLISTS far* doslists;
- REALMODECALL r;
-
- // Get DOS list of lists (INT 21h, Function 52h)
- _fmemset(&r, 0, sizeof(REALMODECALL));
- r.eax = 0x5200;
- if (!DPMI_RealModeInt(0x21, &r))
- return NULL;
-
- // Pointer to DOS list of lists is returned in ES:BX
- doslists = (DOSLISTS far*)
- PMODE_ADDR( _wSelector, MK_FP(r.es, LOWORD(r.ebx)) );
-
- if (GetDosVersionMajor() < 4)
- return doslists->cds + (nDrive * DOS3_CDS_SIZE);
- else
- return doslists->cds + (nDrive * DOS4_CDS_SIZE);
- }
-
- /****************************************************************************
- BOOL isCDROM(int nDrive)
-
- PURPOSE: Tests if nDrive is a CD ROM drive
-
- PARAMETERS: int nDrive The drive to test
-
- RETURNS: TRUE if nDrive is a CD ROM
- *****************************************************************************/
- BOOL isCDROM(int nDrive)
- {
- WORD saveAX, saveBX;
-
- _asm mov cx, nDrive;
- _asm mov ax, 0x150B;
- _asm int 0x2F;
- _asm mov saveAX, ax;
- _asm mov saveBX, bx;
-
- return saveBX == 0xADAD && saveAX != 0;
- }
-
-
- /****************************************************************************
- BOOL isSubstDrive(int nDrive)
-
- PURPOSE: Tests for drives created using the DOS SUBST command
-
- PARAMETERS: int nDrive The drive to test
-
- RETURNS: TRUE if nDrive is a SUBST drive
- *****************************************************************************/
- BOOL isSubstDrive(int nDrive)
- {
- BYTE far* cds; // Current Directory Structure
- WORD cds_flags;
-
- cds = PMODE_ADDR(_wSelector, GetCDS(nDrive));
- cds_flags = *(WORD far*)(cds+CDS_FLAGS);
- if (cds_flags & (CDS_SUBST))
- return TRUE;
-
- return FALSE;
- }
-
- /****************************************************************************
- BOOL isRamDrive(int nDrive)
-
- PURPOSE: Tests for Ram drives
-
- PARAMETERS: int nDrive The drive to test
-
- RETURNS: TRUE if nDrive is a ram drive
-
- NOTES: This function tests to see if the drive has only one FAT. It
- is assumed that if this is true, then the drive must be a RAM drive.
- *****************************************************************************/
- BOOL isRamDrive(int nDrive)
- {
- BYTE far* cds; // Current Directory Structure
- BYTE far* dpb; // Drive Parameter Block
-
- cds = PMODE_ADDR(_wSelector, GetCDS(nDrive));
-
- dpb = *(BYTE far* far*)(cds+CDS_DPB);
- dpb = PMODE_ADDR(_wSelector, dpb);
-
- if (*(dpb+DPB_FATS) == 1)
- return TRUE;
-
- return FALSE;
- }
-
- /****************************************************************************
- WORD FAR PASCAL GetDriveTypeX(int nDrive)
-
- PURPOSE: Determines drive type
-
- PARAMETERS:
- int nDrive The drive number. 0 = A:, 1 = B:,
- 2 = C:, 3 = D:, ...
- RETURNS:
- DRIVE_UNKNOWN Unknown drive type
- DRIVE_NOTEXIST Drive does not exist
- DRIVE_REMOVE Removable (floppy) drive
- DRIVE_FIXED Fixed (hard) drive
- DRIVE_REMOTE Remote (network) drive
- DRIVE_CDROM CD ROM drive
- DRIVE_RAM Ram drive
- DRIVE_SUBST SUBST drive
- *****************************************************************************/
- WORD FAR PASCAL GetDriveTypeX(int nDrive)
- {
- WORD wDriveType;
-
- // Get a new selector, using the current DS as the prototype
- _wSelector = AllocSelector(_DS);
- SetSelectorLimit(_wSelector, 0xFFFF);
-
- wDriveType = GetDriveType(nDrive);
-
- if (isCDROM(nDrive))
- wDriveType = DRIVE_CDROM;
- else
- if (wDriveType != DRIVE_REMOTE && isSubstDrive(nDrive))
- wDriveType = DRIVE_SUBST;
- else
- if (isRamDrive(nDrive))
- wDriveType = DRIVE_RAM;
-
- FreeSelector(_wSelector);
- return wDriveType;
- }
-
- /****************************************************************************
- BOOL FAR PASCAL GetCanonicalPath(LPSTR lpszRelPath, LPSTR lpszTruePath)
-
- PURPOSE: Resolve path string to canonical path string
-
- PARAMETERS:
- LPSTR lpszRelPath Relative path string or directory name
- LPSTR lpszTruePath Destination for canonical fully qualified
- path
- RETURNS:
- TRUE if successful
- *****************************************************************************/
- BOOL FAR PASCAL GetCanonicalPath(LPSTR lpszRelPath, LPSTR lpszTruePath)
- {
- BOOL retval;
- DWORD dw;
- WORD wSelector;
- WORD wSegment;
- LPSTR lpszDosBuf;
- REALMODECALL r;
-
- dw = GlobalDosAlloc(128);
- if (dw == NULL)
- return FALSE;
-
- wSelector = LOWORD(dw);
- wSegment = HIWORD(dw);
-
- lpszDosBuf = MK_FP(wSelector, 0);
- _fmemcpy(lpszDosBuf, lpszRelPath, 128);
-
- r.eax = 0x6000;
- r.ds = wSegment;
- r.esi = 0;
- r.es = wSegment;
- r.edi = 0;
-
- retval = DPMI_RealModeInt(0x21, &r);
-
- _fmemcpy(lpszTruePath, lpszDosBuf, 128);
- GlobalDosFree(wSelector);
-
- return retval;
- }
-
-